package com.stylefeng.guns.modular.system.service.impl;

import com.google.common.collect.Lists;
import com.stylefeng.guns.common.exception.BizExceptionEnum;
import com.stylefeng.guns.common.exception.BussinessException;
import com.stylefeng.guns.common.persistence.dao.DictMapper;
import com.stylefeng.guns.common.persistence.model.Dict;
import com.stylefeng.guns.modular.system.service.IDictService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.stylefeng.guns.common.constant.factory.MutiStrFactory.MUTI_STR_KEY;
import static com.stylefeng.guns.common.constant.factory.MutiStrFactory.MUTI_STR_VALUE;
import static com.stylefeng.guns.common.constant.factory.MutiStrFactory.parseKeyValue;

@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class DictServiceImpl implements IDictService {

    @Resource
    private DictMapper dictMapper;

    @Override
    public void addDict(String dictName, String dictValues) {
        //判断有没有该字典
        Example example = new Example(Dict.class);
        example.createCriteria().andEqualTo("name", dictName).andEqualTo("pid", 0);
        List<Dict> dicts = dictMapper.selectByExample(example);
        if (dicts != null && dicts.size() > 0) {
            throw new BussinessException(BizExceptionEnum.DICT_EXISTED);
        }

        //解析dictValues
        List<Map<String, String>> items = parseKeyValue(dictValues);

        //添加字典
        Dict dict = new Dict();
        dict.setName(dictName);
        dict.setNum(0);
        dict.setPid(0);
        this.dictMapper.insert(dict);

        //添加字典条目
        for (Map<String, String> item : items) {
            String num = item.get(MUTI_STR_KEY);
            String name = item.get(MUTI_STR_VALUE);
            Dict itemDict = new Dict();
            itemDict.setPid(dict.getId());
            itemDict.setName(name);
            try {
                itemDict.setNum(Integer.valueOf(num));
            } catch (NumberFormatException e) {
                throw new BussinessException(BizExceptionEnum.DICT_MUST_BE_NUMBER);
            }
            this.dictMapper.insert(itemDict);
        }
    }

    @Override
    public void editDict(Integer dictId, String dictName, String dicts) {
        //删除之前的字典
        this.deleteDict(dictId);

        //重新添加新的字典
        this.addDict(dictName, dicts);
    }

    @Override
    public void deleteDict(Integer dictId) {
        //删除这个字典的子词典
        Dict query = new Dict();
        query.setPid(dictId);
        dictMapper.delete(query);
        //删除这个词典
        dictMapper.deleteByPrimaryKey(dictId);
    }

    @Override
    public void addDictItems(String pDictName, Dict... dicts) {

        // 先根据字典名称查找pid
        Example example = new Example(Dict.class);
        example.createCriteria().andEqualTo("name", pDictName).andEqualTo("pid", 0);
        List<Dict> dictList = dictMapper.selectByExample(example);
        // 已存在的
        List<Dict> subDicts = Lists.newArrayList();
        Integer pid;
        if (CollectionUtils.isEmpty(dictList)) {
            //添加字典
            Dict dict = new Dict();
            dict.setName(pDictName);
            dict.setNum(0);
            dict.setPid(0);
            this.dictMapper.insert(dict);
            pid = dict.getId();

            Dict queryModel = new Dict();
            queryModel.setPid(pid);
            subDicts = dictMapper.select(queryModel);
        } else {
            pid = dictList.get(0).getId();
        }

        List<Dict> dictList1 = Arrays.stream(dicts).peek(dict -> dict.setPid(pid)).collect(Collectors.toList());
        List<Dict> needInsert = ListUtils.subtract(dictList1, subDicts);
        if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(needInsert)) {
            dictMapper.insertList(needInsert);
        }
    }
}
